package com.cskaoyan.javase.oop2._1extends._2conversion;

/**
 * 引用数据类型的类型转换
 *
 * 1.引用数据类型的类型转换,要想发生,有什么前提条件呢?
 *      引用数据类型的类型转换必须发生在继承中的父子类之间
 *      如果没有继承,Java就不存在引用数据类型的类型转换
 *      继承的优点: 继承打破了Java引用数据类型的类型限制,有了继承,就有了引用数据类型的类型转换
 *
 * 2.引用数据类型的类型转换,分几类?
 *      两类
 *      自动类型转换: 指的是编译器自动完成类型转换,无需程序员写额外代码
 *      强制类型转换: 指的是由程序员手动写特殊语法,完成类型转换
 *
 * 3.引用数据类型的类型转换,转换的是什么的数据类型?
 *      转换的是引用的数据类型
 *      万万不可能转换对象的数据类型
 *
 * 4.引用数据类型的自动类型转换
 *      发生自动类型转换的条件:
 *          把子类对象的引用,转换成父类引用
 *          子类引用 --> 父类引用
 *          这个过程编译器自动完成,是自动类型转换
 *          这是因为子类"is-a"父类,子类本来就可以当父类用
 *          所以这里是自动转换
 *
 *      引用数据类型的自动类型转换特殊的称呼,简称:
 *          从继承的方向上来说,子类-->父类,属于向上
 *          所以引用数据类型的自动类型转换,简称"向上转型"
 *
 * 5.引用数据类型的强制类型转换
 *      a.条件/发生的场景/能够通过编译的:
 *      父类引用 --> 子类引用
 *      这个过程,需要程序员手动写代码完成
 *      语法:
 *          子类引用 对象名 = (子类类名)父类引用;
 *      在Java当中,只要是按照以上语法写强转
 *      该强转都是可以通过编译的
 *
 *      b.成功的前提:
 *          如果直接把一个父类对象,通过强转当成子类类型去使用,虽然可以通过编译
 *          但显然是不可能成功的
 *          强转失败,代码运行报错
 *          抛出异常: ClassCastException
 *          所以引用数据类型的强制类型转换,它成功的条件是很苛刻的
 *          它具体成功的条件后面再讲.
 *
 *      c.引用数据类型的强制类型转换简称:
 *          向下转型
 *          继承方向上是 从上到下的
 *
 * @since 15:05
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        /*
            以下代码是父类引用指向子类对象
            正常情况下来说,子类对象就应该用子类引用接收
         */
        Phone p = new HuaWeiPhone();

        // 子类引用指向子类对象
        HuaWeiPhone hp = new HuaWeiPhone();
        /*
            父类引用指向子类对象,相当于把子类引用赋值给父类引用
            原本该引用数据类型变量的类型是HuaWeiPhone
            现在变成了Phone
            数据类型发生了改变
            这里明显发生了类型转换,而且没有写额外代码
            这是引用数据类型的自动类型转换
         */
        Phone p2 = hp;
        System.out.println("---------------------");
        Father f = new Father();
        /*
            把一个父类对象
            通过强转
            当成一个子类类型去使用
            这肯定是不可能的
            因为父类和子类没有"is-a"关系
            所以这里的强转是必然失败的
            会抛出异常:
            ClassCastException
         */
        Son sf = (Son) f;

    }
}
class Father{}
class Son extends Father{}
class Phone {
    double price;

    public void call() {
        System.out.println("打电话");
    }
}

class HuaWeiPhone extends Phone {
    String brand = "华为";
}